;-------------------------------------------------------------------------------
; dabort.asm
;
; Copyright (C) 2009-2016 Texas Instruments Incorporated - www.ti.com
;
;
;  Redistribution and use in source and binary forms, with or without
;  modification, are permitted provided that the following conditions
;  are met:
;
;    Redistributions of source code must retain the above copyright
;    notice, this list of conditions and the following disclaimer.
;
;    Redistributions in binary form must reproduce the above copyright
;    notice, this list of conditions and the following disclaimer in the
;    documentation and/or other materials provided with the
;    distribution.
;
;    Neither the name of Texas Instruments Incorporated nor the names of
;    its contributors may be used to endorse or promote products derived
;    from this software without specific prior written permission.
;
;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
;  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
;  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
;  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
;  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
;  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
;  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
;

    section .text:CODE
    arm


;-------------------------------------------------------------------------------
; Run Memory Test

    import    custom_dabort
    public    _dabort


_dabort
        stmfd    r13!, {r0 - r12, lr}; push registers and link register on to stack

        ldr        r12, esmsr3            ; ESM Group3 status register
        ldr        r0,  [r12]
        tst        r0,  #0x8            ; check if bit 3 is set, this indicates uncorrectable ECC error on B0TCM
        bne        ramErrorFound
        tst        r0, #0x20            ; check if bit 5 is set, this indicates uncorrectable ECC error on B1TCM
        bne        ramErrorFound2

noRAMerror
        tst        r0, #0x80            ; check if bit 7 is set, this indicates uncorrectable ECC error on ATCM
        bne        flashErrorFound

        bl        custom_dabort        ; custom data abort handler required
                                    ; If this custom handler is written in assembly, all registers used in the routine
                                    ; and the link register must be saved on to the stack upon entry, and restored before
                                    ; return from the routine.

        ldmfd    r13!, {r0 - r12, lr}; pop registers and link register from stack
        subs    pc, lr, #8            ; restore state of CPU when abort occurred, and branch back to instruction that was aborted

ramErrorFound
        ldr        r1, ramctrl            ; RAM control register for B0TCM TCRAMW
        ldr        r2, [r1]
        tst        r2, #0x100            ; check if bit 8 is set in RAMCTRL, this indicates ECC memory write is enabled
        beq        ramErrorReal
        mov        r2, #0x20
        str        r2, [r1, #0x10]        ; clear RAM error status register

        mov        r2, #0x08
        str        r2, [r12]            ; clear ESM group3 channel3 flag for uncorrectable RAM ECC errors
        mov        r2, #5
        str        r2, [r12, #0x18]    ; The nERROR pin will become inactive once the LTC counter expires

        ldmfd    r13!, {r0 - r12, lr}
        subs    pc, lr, #4            ; branch to instruction after the one that caused the abort
                                    ; this is the case because the data abort was caused intentionally
                                    ; and we do not want to cause the same data abort again.

ramErrorFound2
        ldr        r1, ram2ctrl        ; RAM control register for B1TCM TCRAMW
        ldr        r2, [r1]
        tst        r2, #0x100            ; check if bit 8 is set in RAMCTRL, this indicates ECC memory write is enabled
        beq        ramErrorReal
        mov        r2, #0x20
        str        r2, [r1, #0x10]        ; clear RAM error status register

        mov        r2, #0x20
        str        r2, [r12]            ; clear ESM group3 flags channel5 flag for uncorrectable RAM ECC errors
        mov        r2, #5
        str        r2, [r12, #0x18]    ; The nERROR pin will become inactive once the LTC counter expires

        ldmfd    r13!, {r0 - r12, lr}
        subs    pc, lr, #4            ; branch to instruction after the one that caused the abort
                                    ; this is the case because the data abort was caused intentionally
                                    ; and we do not want to cause the same data abort again.


ramErrorReal
        b        ramErrorReal        ; branch here forever as continuing operation is not recommended

flashErrorFound
        ldr        r1, flashbase
        ldr        r2, [r1, #0x6C]        ; read FDIAGCTRL register

        mov     r2, r2, lsr #16
        tst        r2, #5                ; check if bits 19:16 are 5, this indicates diagnostic mode is enabled
        beq        flashErrorReal
        mov        r2, #1
        mov     r2, r2, lsl #8

        str        r2, [r1, #0x1C]        ; clear FEDACSTATUS error flag

        mov        r2, #0x80
        str        r2, [r12]            ; clear ESM group3 flag for uncorrectable flash ECC error
        mov        r2, #5
        str        r2, [r12, #0x18]    ; The nERROR pin will become inactive once the LTC counter expires

        ldmfd    r13!, {r0 - r12, lr}
        subs    pc, lr, #4            ; branch to instruction after the one that caused the abort
                                    ; this is the case because the data abort was caused intentionally
                                    ; and we do not want to cause the same data abort again.


flashErrorReal
        b        flashErrorReal        ; branch here forever as continuing operation is not recommended

esmsr3        dcd    0xFFFFF520
ramctrl        dcd    0xFFFFF800
ram2ctrl    dcd    0xFFFFF900
ram1errstat    dcd    0xFFFFF810
ram2errstat    dcd    0xFFFFF910
flashbase    dcd    0xFFF87000



    end
